<template>
    <div class="page-container">
        <tools-bar ref="toolsBar" @customEvent="handleToolsBarClick" />
        <div class="pannel-container">
            <div class="left-pannel">
                <mini-list :queryUrl="'listOperate'" @addClick="handleAddNode" :listHeight="shortListHeight" />
                <mini-list :queryUrl="'lsitHistoryModels'" @addClick="handleAddNode" :listHeight="shortListHeight" />
            </div>
            <div class="x6-canvas" id="x6-canvas" />
            <div class="right-pannel">
                <mini-list :queryUrl="'hyperParams'" style="height: 100%" @addClick="handleAddNode"
                    :listHeight="longListHeight" />
            </div>
        </div>
    </div>
</template>

<script setup name="X6Canvas">
import { Graph, Shape, Path } from '@antv/x6';
import { onMounted, reactive, ref, provide, computed } from 'vue-demi';
import MiniList from '@/components/MiniList/index.vue'
import { startDragToGraph } from "./drag.jsx";
import ToolsBar from '@/components/ToolsBar/index.vue'
import useX6Store from '@/store/modules/x6canvas'

const x6Store = useX6Store()

let graph = null
const toolsBar = ref(null)

/**
    Init graph config: graph, connector, etc.
*/
const init = (x6id) => {
    Graph.registerEdge(
        'dag-edge',
        {
            inherit: 'edge',
            attrs: {
                line: {
                    stroke: '#808080',
                    strokeWidth: 1,
                    targetMarker: null,
                },
            },
        },
        true,
    )

    Graph.registerConnector(
        'algo-connector',
        (s, e) => {
            const offset = 4
            const deltaY = Math.abs(e.y - s.y)
            const control = Math.floor((deltaY / 3) * 2)

            const v1 = { x: s.x, y: s.y + offset + control }
            const v2 = { x: e.x, y: e.y - offset - control }

            return Path.normalize(
                `M ${s.x} ${s.y}
       L ${s.x} ${s.y + offset}
       C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
       L ${e.x} ${e.y}
      `,
            )
        },
        true,
    )

    // console.log('Initializing...', x6id)

    if (graph) {
        graph.dispose()
    }

    graph = new Graph({
        container: document.getElementById('x6-canvas'),
        autoResize: true,
        background: {
            color: '#d9ecff',
        },
        grid: {
            size: 10,
            visible: true,
        },
        panning: {
            enabled: true,
            eventTypes: ['leftMouseDown', 'mouseWheel'],
        },
        mousewheel: {
            enabled: true,
            modifiers: 'ctrl',
            factor: 1.1,
            maxScale: 1.5,
            minScale: 0.5,
        },
        selecting: {
            enabled: true,
            multiple: true,
            rubberEdge: true,
            rubberNode: true,
            modifiers: 'shift',
            rubberband: true,
        },
        connecting: {
            anchor: "center",
            connectionPoint: "anchor",
            allowBlank: false,
            snap: true,
            connector: 'algo-connector',
            createEdge () {
                return graph.createEdge({
                    shape: 'dag-edge',
                })
            },
        },
    });


    const data = x6Store.canvas.get(x6id)
    if (data) {
        data.nodes.forEach(node => {
            graph.addNode(node)
        })
        setTimeout(() => {
            data.edges.forEach(edge => {
                graph.addEdge(edge)
            })
        }, 50);
    }

    /**
        Handle mouse enter event
    */
    graph.on("node:mouseenter", () => {
        const container = document.getElementById('x6-canvas');
        const ports = container.querySelectorAll(".x6-port-body");
        showPorts(ports, true);
    });

    /**
        Handle mouse leave event
    */
    graph.on("node:mouseleave", () => {
        const container = document.getElementById('x6-canvas');
        const ports = container.querySelectorAll(".x6-port-body");
        showPorts(ports, false);
    });

    /**
        Method for call Toolsbar buttons
    */
    graph.callForToolsBar = (type) => {
        // console.log(type)
        toolsBar.value.initToolsBar(type)
    }
}

/**
    Handle hide/show node ports
*/
const showPorts = (ports, show) => {
    for (let i = 0, len = ports.length; i < len; i = i + 1) {
        ports[i].style.visibility = show ? "visible" : "hidden";
    }
}

/**
    Create new node
*/
const handleAddNode = (item, e) => {
    // console.log(item, e)
    startDragToGraph(graph, item, e)
}


/**
    Tools Bar button click event handler
*/
const handleToolsBarClick = (funcDispatch) => {
    funcDispatch(graph)
}

const exportData = () => {
    return {
        nodes: graph.getNodes(),
        edges: graph.getEdges()
    }
}

const shortListHeight = computed(() => {
    return parseInt((document.body.offsetHeight - 136) / 2 * 0.85 - 90)
})

const longListHeight = computed(() => {
    return parseInt((document.body.offsetHeight - 136) * 0.85 - 90)
})

onMounted(() => {
    // init('x6canvas-0')
})

defineExpose({
    init,
    exportData
})

</script>

<style lang="scss" scoped>
.page-container {
    width: 100%;
    display: flex;
    flex-direction: column;
    .pannel-container {
        width: 100%;
        display: flex;
        .left-pannel {
            width: 20%;
            height: 100%;
            display: flex;
            flex-direction: column;
        }
        .x6-canvas {
            flex: 1;
            height: 100% !important;
        }
        .right-pannel {
            width: 20%;
            height: 100%;
        }
    }
}
</style>